package com.megaspacevr.controller;

import com.megaspacevr.entity.PersonalInfo;
import com.megaspacevr.entity.Result;
import com.megaspacevr.entity.vo.PersonalInfoVO;
import com.megaspacevr.service.PersonalInfoService;
import com.megaspacevr.utils.ResultUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

/**
 * <p>
 * 个人信息表-用户填写的个人资料 前端控制器
 * </p>
 *
 * @author yezi
 * @since 2025-06-17
 */
@Slf4j
@RestController
@Validated
@RequestMapping("/personalInfo")
@Tag(name = "个人信息管理", description = "用户个人信息相关接口")
@CrossOrigin(origins = "*")
public class PersonalInfoController {

    @Autowired
    private PersonalInfoService personalInfoService;

    /**
     * 保存或更新个人信息
     * @param personalInfoVO 个人信息VO
     * @return 操作结果
     */
    @PostMapping("/save")
    @Operation(summary = "保存个人信息", description = "用户提交个人信息表单")
    public Result<PersonalInfo> savePersonalInfo(@Valid @RequestBody PersonalInfoVO personalInfoVO) {
        log.info("收到保存个人信息请求");
        log.info("请求数据 - userToken: {}, name: {}, phone: {}, gender: {}, age: {}", 
                personalInfoVO.getUserToken(), personalInfoVO.getName(), personalInfoVO.getPhone(),
                personalInfoVO.getGender(), personalInfoVO.getAge());
        
        try {
            // 检查手机号是否已存在
            if (personalInfoService.isPhoneExists(personalInfoVO.getPhone(), null)) {
                return ResultUtil.fail("该手机号已被使用，每个手机号只能预约一次");
            }
            
            // 转换VO为实体对象
            PersonalInfo personalInfo = new PersonalInfo();
            BeanUtils.copyProperties(personalInfoVO, personalInfo);
            
            // 保存个人信息
            PersonalInfo savedInfo = personalInfoService.saveOrUpdatePersonalInfo(personalInfo);
            
            log.info("个人信息保存成功 - ID: {}", savedInfo.getId());
            return ResultUtil.success(savedInfo);
            
        } catch (Exception e) {
            log.error("保存个人信息失败", e);
            return ResultUtil.fail("保存个人信息失败：" + e.getMessage());
        }
    }

    /**
     * 更新个人信息
     * @param id 个人信息ID
     * @param personalInfoVO 个人信息VO
     * @return 操作结果
     */
    @PutMapping("/update/{id}")
    @Operation(summary = "更新个人信息", description = "更新用户个人信息")
    public Result<PersonalInfo> updatePersonalInfo(@PathVariable Long id, 
                                                 @Valid @RequestBody PersonalInfoVO personalInfoVO) {
        log.info("更新个人信息 - ID: {}, userToken: {}, phone: {}", 
                id, personalInfoVO.getUserToken(), personalInfoVO.getPhone());
        
        try {
            // 检查个人信息是否存在
            PersonalInfo existingInfo = personalInfoService.getById(id);
            if (existingInfo == null) {
                return ResultUtil.fail("个人信息不存在");
            }
            
            // 检查手机号是否已被其他人使用
            if (personalInfoService.isPhoneExists(personalInfoVO.getPhone(), id)) {
                return ResultUtil.fail("该手机号已被使用，每个手机号只能预约一次");
            }
            
            // 更新信息
            BeanUtils.copyProperties(personalInfoVO, existingInfo);
            existingInfo.setId(id);
            
            PersonalInfo updatedInfo = personalInfoService.saveOrUpdatePersonalInfo(existingInfo);
            
            log.info("个人信息更新成功 - ID: {}", updatedInfo.getId());
            return ResultUtil.success(updatedInfo);
            
        } catch (Exception e) {
            log.error("更新个人信息失败", e);
            return ResultUtil.fail("更新个人信息失败：" + e.getMessage());
        }
    }

    /**
     * 根据用户Token获取个人信息
     * @param userToken 用户标识
     * @return 个人信息
     */
    @GetMapping("/by-token/{userToken}")
    @Operation(summary = "获取用户个人信息", description = "根据用户Token获取默认个人信息")
    public Result<PersonalInfo> getPersonalInfoByUserToken(@PathVariable String userToken) {
        log.info("获取用户个人信息 - userToken: {}", userToken);
        
        try {
            PersonalInfo personalInfo = personalInfoService.getPersonalInfoByUserToken(userToken);
            if (personalInfo == null) {
                return ResultUtil.fail("未找到用户个人信息");
            }
            
            return ResultUtil.success(personalInfo);
            
        } catch (Exception e) {
            log.error("获取用户个人信息失败", e);
            return ResultUtil.fail("获取个人信息失败：" + e.getMessage());
        }
    }

    /**
     * 根据手机号检查是否已存在个人信息
     * @param phone 手机号
     * @return 检查结果
     */
    @GetMapping("/check-phone")
    @Operation(summary = "检查手机号", description = "检查手机号是否已被使用")
    public Result<Boolean> checkPhoneExists(@RequestParam String phone) {
        log.info("检查手机号是否存在 - phone: {}", phone);
        
        try {
            boolean exists = personalInfoService.isPhoneExists(phone, null);
            return ResultUtil.success(exists);
            
        } catch (Exception e) {
            log.error("检查手机号失败", e);
            return ResultUtil.fail("检查手机号失败：" + e.getMessage());
        }
    }

    /**
     * 根据手机号获取个人信息
     * @param phone 手机号
     * @return 个人信息
     */
    @GetMapping("/by-phone/{phone}")
    @Operation(summary = "根据手机号获取个人信息", description = "用于预约时快速填充个人信息")
    public Result<PersonalInfo> getPersonalInfoByPhone(@PathVariable String phone) {
        log.info("根据手机号获取个人信息 - phone: {}", phone);
        
        try {
            PersonalInfo personalInfo = personalInfoService.getPersonalInfoByPhone(phone);
            if (personalInfo == null) {
                return ResultUtil.fail("未找到对应的个人信息");
            }
            
            return ResultUtil.success(personalInfo);
            
        } catch (Exception e) {
            log.error("根据手机号获取个人信息失败", e);
            return ResultUtil.fail("获取个人信息失败：" + e.getMessage());
        }
    }

    /**
     * 设置默认个人信息
     * @param userToken 用户标识
     * @param personalInfoId 个人信息ID
     * @return 操作结果
     */
    @PostMapping("/set-default")
    @Operation(summary = "设置默认个人信息", description = "将指定的个人信息设置为默认")
    public Result<String> setDefaultPersonalInfo(@RequestParam String userToken, 
                                               @RequestParam Long personalInfoId) {
        log.info("设置默认个人信息 - userToken: {}, personalInfoId: {}", userToken, personalInfoId);
        
        try {
            // 检查个人信息是否存在且属于该用户
            PersonalInfo personalInfo = personalInfoService.getById(personalInfoId);
            if (personalInfo == null) {
                return ResultUtil.fail("个人信息不存在");
            }
            
            if (!userToken.equals(personalInfo.getUserToken())) {
                return ResultUtil.fail("无权操作此个人信息");
            }
            
            personalInfoService.setDefaultPersonalInfo(userToken, personalInfoId);
            
            log.info("设置默认个人信息成功");
            return ResultUtil.success("设置成功");
            
        } catch (Exception e) {
            log.error("设置默认个人信息失败", e);
            return ResultUtil.fail("设置默认个人信息失败：" + e.getMessage());
        }
    }
}
